package io.jpress.pro.filesync;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.io.File;
import java.util.concurrent.TimeUnit;


public class RemoteFilesRecord {

    private static Cache<String, TimeSize> createdFiles = Caffeine.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();


    private static Cache<String, TimeSize> changedFiles = Caffeine.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();


    private static Cache<String, Long> deletedFiles = Caffeine.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();


    public static void recordCreatedFile(File file) {
        createdFiles.put(file.getAbsolutePath(), new TimeSize(file));
    }


    public static boolean isCreatedRecord(File file) {
        TimeSize cachedTimeSize = createdFiles.getIfPresent(file.getAbsolutePath());
        if (cachedTimeSize == null) {
            return false;
        }
        return cachedTimeSize.equals(new TimeSize(file));
    }


    public static void recordChangedFile(File file) {
        changedFiles.put(file.getAbsolutePath(), new TimeSize(file));
    }

    public static boolean isChangedRecord(File file) {
        TimeSize cachedTimeSize = changedFiles.getIfPresent(file.getAbsolutePath());
        if (cachedTimeSize == null) {
            return false;
        }
        return cachedTimeSize.equals(new TimeSize(file));
    }


    public static void recordDeleteFile(File file) {
        deletedFiles.put(file.getAbsolutePath(), System.currentTimeMillis());
    }


    public static boolean isDeleteRecord(File file) {
        Long cachedTimeSize = deletedFiles.getIfPresent(file.getAbsolutePath());
        return cachedTimeSize != null;
    }


    public static class TimeSize {

        private final long time;
        private final long size;

        public TimeSize(File file) {
            this.time = file.lastModified();
            this.size = file.length();
        }


        @Override
        public int hashCode() {
            return (int) (time ^ size);
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (this.getClass() == obj.getClass()) {
                TimeSize ts = (TimeSize) obj;
                return ts.time == this.time && ts.size == this.size;
            }
            return false;
        }

        @Override
        public String toString() {
            return "TimeSize{" +
                    "time=" + time +
                    ", size=" + size +
                    '}';
        }
    }
}
